Skip to content

ci: open dev-to-main PR instead of pushing protected main#1320

Open
andreidavid wants to merge 1 commit into
devfrom
chore/release-earn-apps-github-token-v2
Open

ci: open dev-to-main PR instead of pushing protected main#1320
andreidavid wants to merge 1 commit into
devfrom
chore/release-earn-apps-github-token-v2

Conversation

@andreidavid

@andreidavid andreidavid commented Mar 2, 2026

Copy link
Copy Markdown
Contributor

Description

This PR updates the release-earn-apps workflow to stop failing on protected main by creating/reusing a dev -> main PR instead of pushing directly to main.

Changes

  • Replaced direct git push origin main logic with an automated PR creation step using actions/github-script@v7.
  • Added pull-requests: write to workflow permissions.
  • Kept the step idempotent: if a dev -> main PR already exists, it reuses it.

Benefits

  1. Works with branch protection rules that block direct pushes to main.
  2. Removes need for bypass permissions or privileged user tokens for main updates.
  3. Keeps release flow automated while preserving required review/merge controls.

Testing

  • Ran the workflow logic review in branch and confirmed the old failing push step is removed.
  • Verified the new step checks for an existing PR and only creates one when needed.

Next steps

  • Run the release workflow once and verify it opens/reuses the dev -> main PR.
  • Confirm required reviewers/checks on main proceed as expected.

Additional Notes

This PR is intentionally scoped to branch-protection compatibility in release-earn-apps; other previously merged workflow improvements are not reintroduced here.

Please review and provide any feedback or suggestions for improvement.

Summary by CodeRabbit

  • Chores
    • Improved pull request automation for development branch integration. The system now intelligently manages pull requests from development to main, automatically creating new requests when needed while avoiding duplicates.

@coderabbitai

coderabbitai Bot commented Mar 2, 2026

Copy link
Copy Markdown
Contributor

Walkthrough

Workflow automation updated to replace manual rebasing with automated PR creation from dev to main. Includes logic to check for existing PRs before creating new ones.

Changes

Cohort / File(s) Summary
Workflow Automation
.github/workflows/release-earn-apps.yaml
Added pull-request write permission; replaced shell commands with GitHub Script to check for and create PRs from dev to main automatically.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~8 minutes

Poem

Branches merge with grace divine,
Dev to main in perfect line,
Scripts now check before they dance,
No duplicate PRs by chance! 🚀

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed Title accurately summarizes the main change: replacing direct main pushes with automated PR creation for branch protection compliance.
Description check ✅ Passed Description comprehensively covers all template sections with clear details on changes, benefits, testing approach, and next steps.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch chore/release-earn-apps-github-token-v2

Tip

Try Coding Plans. Let us write the prompt for your AI agent so you can ship faster (with fewer bugs).
Share your feedback on Discord.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.github/workflows/release-earn-apps.yaml:
- Around line 60-68: The checkout step is not pinned which can mismatch with the
hardcoded head = 'dev' used when creating the PR; update the checkout action
(the step that uses actions/checkout) to include ref: 'dev' so the workspace
actually checks out the dev branch before tagging and PR creation, and leave the
PR creation logic that sets head = 'dev' unchanged; target the checkout step by
its uses: 'actions/checkout' reference and ensure ref: 'dev' is added.
- Around line 86-93: Wrap the github.rest.pulls.create call in a try-catch and
handle HTTP 422 (already_exists) idempotently: catch errors from the create call
(where the code currently does const { data: pr } = await
github.rest.pulls.create({...})), and if err.status === 422, re-query the repo
for the matching PR (e.g., via github.rest.pulls.list with the same
head/base/title) and use the existing PR data instead of failing; for other
errors rethrow or log and fail as appropriate.

ℹ️ Review info

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Knowledge base: Disabled due to Reviews -> Disable Knowledge Base setting

📥 Commits

Reviewing files that changed from the base of the PR and between dccea4f and d35f92e.

📒 Files selected for processing (1)
  • .github/workflows/release-earn-apps.yaml

Comment on lines +60 to +68
- name: Create or reuse PR from dev to main
uses: actions/github-script@v7
with:
github-token: ${{ github.token }}
script: |
const owner = context.repo.owner
const repo = context.repo.repo
const head = 'dev'
const base = 'main'

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

cat -n .github/workflows/release-earn-apps.yaml

Repository: OasisDEX/summerfi-monorepo

Length of output: 4721


Checkout must pin to dev or workflow dispatch branch mismatch can cause wrong release.

Workflow can be dispatched from any branch but checkout is not pinned. Line 67 hardcodes head = 'dev' for PR creation, so releasing from main checks out main, tags main, but tries to open PR from dev → main.

Add ref: dev to checkout step.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/release-earn-apps.yaml around lines 60 - 68, The checkout
step is not pinned which can mismatch with the hardcoded head = 'dev' used when
creating the PR; update the checkout action (the step that uses
actions/checkout) to include ref: 'dev' so the workspace actually checks out the
dev branch before tagging and PR creation, and leave the PR creation logic that
sets head = 'dev' unchanged; target the checkout step by its uses:
'actions/checkout' reference and ensure ref: 'dev' is added.

Comment on lines +86 to +93
const { data: pr } = await github.rest.pulls.create({
owner,
repo,
head,
base,
title,
body,
})

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

find . -name "release-earn-apps.yaml" -type f

Repository: OasisDEX/summerfi-monorepo

Length of output: 112


🏁 Script executed:

cat -n .github/workflows/release-earn-apps.yaml | sed -n '70,110p'

Repository: OasisDEX/summerfi-monorepo

Length of output: 1610


🏁 Script executed:

cat -n .github/workflows/release-earn-apps.yaml

Repository: OasisDEX/summerfi-monorepo

Length of output: 4721


🌐 Web query:

GitHub REST API PR creation 422 error when PR already exists

💡 Result:

When you call POST /repos/{owner}/{repo}/pulls to create a PR and GitHub returns 422 Unprocessable Entity, one common cause is that an open PR already exists for the same headbase combination (the API responds with a validation error like “A pull request already exists for owner:branch”) [3]. GitHub documents that this endpoint can return 422 “Validation failed” [1].

GitHub’s REST API does not provide an “idempotent create PR” option (i.e., you can’t ask it to return 201/OK if the PR already exists); you need to handle it in your client by detecting the existing PR and treating that case as success [2].

Practical fix (recommended pattern)

  1. Before creating, query for an existing PR using List pull requests with head and (optionally) base filters:
    • GET /repos/{owner}/{repo}/pulls?state=open&head=OWNER:branch&base=main
      GitHub supports filtering PRs by head in user:ref-name format and by base branch name [1].
  2. If the list returns a PR, reuse its number/URL instead of calling create again.
  3. Otherwise, call Create a pull request.

This avoids relying on parsing the 422 message, and prevents repeated create attempts that will always fail once a PR exists. [1]


🌐 Web query:

GitHub API pulls.create 422 Unprocessable Entity error conditions

💡 Result:

For POST /repos/{owner}/{repo}/pulls (“pulls.create”), GitHub returns 422 Unprocessable Entity when the request can’t be validated/processed (or the endpoint is being “spammed”). (docs.github.com)

Common 422 causes for creating a pull request:

  • Missing required fields in the JSON body:

    • head is required (docs.github.com)
    • base is required (docs.github.com)
    • title is required unless you supply issue (and issue is required unless you supply title) (docs.github.com)
    • These typically show up as "message": "Validation Failed" with an entry in errors[] like code: "missing_field". (docs.github.com)
  • Invalid head (very common):

    • The branch name doesn’t exist on GitHub (only local / not pushed yet), or
    • For a PR from a fork, head must be namespaced like username:branch (otherwise it’s “invalid”). (docs.github.com)
  • Invalid base:

    • base must be an existing branch on the current repo, and you can’t target a base branch in a different repository. (docs.github.com)
  • No commits/diffs between head and base:

    • GitHub can reject the PR with a validation error like “No commits between …”. (stackoverflow.com)
  • A PR already exists for the same head:

    • Often returned as a "code": "custom" validation error with a message like “A pull request already exists for …”. (knowledge.broadcom.com)
  • GitHub can’t read the refs you referenced (permissions / token scopes):

    • Example validation error: "not all refs are readable", commonly fixed by ensuring the token/app has appropriate Contents: read access. (stackoverflow.com)

How to quickly pinpoint which one you hit:

  • Inspect the response body’s errors[] entries (code values like missing_field, invalid, already_exists, unprocessable, custom)—GitHub documents what these codes mean. (docs.github.com)

Citations:


Handle concurrent PR creation to prevent 422 errors.

The list check at lines 72-84 doesn't prevent the race condition when two workflow runs execute concurrently and both pass the check before either creates the PR. Add try-catch on 422 to handle idempotently.

Suggested fix
-            const { data: pr } = await github.rest.pulls.create({
-              owner,
-              repo,
-              head,
-              base,
-              title,
-              body,
-            })
-
-            core.info(`Created PR: #${pr.number} ${pr.html_url}`)
+            try {
+              const { data: pr } = await github.rest.pulls.create({
+                owner,
+                repo,
+                head,
+                base,
+                title,
+                body,
+              })
+              core.info(`Created PR: #${pr.number} ${pr.html_url}`)
+            } catch (error) {
+              if (error.status === 422) {
+                core.info('PR already exists; skipping.')
+                return
+              }
+              throw error
+            }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const { data: pr } = await github.rest.pulls.create({
owner,
repo,
head,
base,
title,
body,
})
try {
const { data: pr } = await github.rest.pulls.create({
owner,
repo,
head,
base,
title,
body,
})
core.info(`Created PR: #${pr.number} ${pr.html_url}`)
} catch (error) {
if (error.status === 422) {
core.info('PR already exists; skipping.')
return
}
throw error
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/release-earn-apps.yaml around lines 86 - 93, Wrap the
github.rest.pulls.create call in a try-catch and handle HTTP 422
(already_exists) idempotently: catch errors from the create call (where the code
currently does const { data: pr } = await github.rest.pulls.create({...})), and
if err.status === 422, re-query the repo for the matching PR (e.g., via
github.rest.pulls.list with the same head/base/title) and use the existing PR
data instead of failing; for other errors rethrow or log and fail as
appropriate.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant